// Please inlcude "tgl.h" and using namespace "tgl"
#include "tgl.h"

using namespace tgl; 

// Vertices data
float vertices[] = {
    -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
     0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
     0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
     0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
     0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
    -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

    -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
    -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
    -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

     0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
     0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
     0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
     0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
     0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

    -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
     0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
     0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
     0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
     0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
     0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
    -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
};

// Light
Light* light = new PointLight(Vector3(1.0f, 1.0f, -1.0f));

// Material
Material material("material", WHITE, Vector3(0.1f, 0.1f, 0.1f), WHITE, 32);

int main()
{
   // Create a window
   Window window(800, 600, "Test");

   // Read and complie shader
   Shader shader("testVertex.shader", "testFragment.shader");

   // Build a render pipeline
   window.BuildPipeline(vertices, sizeof(vertices), nullptr, 0, [&]() -> void {

      // TBO
      tgl::TexInfo TBO_info1 = window.GenerateTBO("wall.jpg", 0);
      window.SendDataToTBO(TBO_info1, RGB_MODE);
      tgl::TexInfo TBO_info2 = window.GenerateTBO("awesomeface.png", 1);
      window.SendDataToTBO(TBO_info2, RGBA_MODE);

      // Attribute Pointer
      window.SetAttributePointer(0, 3, 5, 0);
      window.SetAttributePointer(1, 2, 5, 3);

      // Set uniform
      shader.Use();
      shader.SetUniform("wallTexture", 0);
      shader.SetUniform("smileTexture", 1);

      // Render iteration
      window.Render(0.0f, 0.0f, 0.0f, 1.0f, [&]() -> void {
         
         // M
         Matrix model = IMAT;

         // V
         Matrix view = IMAT;
         float timeValue = (float)glfwGetTime();
         Camera camera(Vector3(0.0f, 1.0f, 3.0f), 
            -15.0f + 15.0f * glm::sin(timeValue),
            180.0f, 
            WORLD_Y);
         view = camera.GetViewMatrix();

         // P
         Matrix projection = IMAT;
         projection = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f);

         // MVP Transform
         Matrix trans = projection * view * model;

         shader.Use();
         shader.SetUniform("trans", trans);

         // Render
         window.DrawArrays(0, 36);
         });

      });

   return 0;
}